package com.ai.vita.redis.controller;

import com.ai.vita.redis.client.RedisClient;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import redis.clients.jedis.Jedis;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * 首页.
 */
@Controller
public class IndexController {

    private static final Logger LOGGER = LoggerFactory.getLogger(IndexController.class);

    /**
     * 获取合适的客户端.
     * @param ip 客户端ip
     * @param props 客户端属性
     * @return 客户端
     */
    private Jedis getJedis(String ip, String[] props){
        String name = props[0];
        String host = props[1];
        String port = props[2];
        String auth = null;
        if(props.length == 4){
            auth = props[3];
        }
        return RedisClient.get(ip + name, host, Integer.parseInt(port), auth);
    }

    /**
     * 到redis里取值.
     * @param jedis
     * @param key
     * @param type
     * @return
     */
    private Map<String, String> getValue(Jedis jedis, String key, String type){
        Map<String, String> reMap = new HashMap<>();
        reMap.put("type", type);
        switch (type){
            case "string" :
                //字符串类型的值
                try{
                    String value = jedis.get(key);
                    reMap.put("value", value);
                }catch (Exception e){
                    reMap = getValue(jedis, key, "hash");
                }
                break;
            case "hash" :
                //hash类型的值
                try {
                    Long size = jedis.hlen(key);
                    Map<String, String> value;
                    if(size > RedisClient.getMaxRecordNumber()){
                        size = RedisClient.getMaxRecordNumber();
                        value = new HashMap<>();
                        String[] keys = jedis.hkeys(key).toArray(new String[0]);
                        for (int i = 0;i < size;i++){
                            String k = keys[i];
                            value.put(k, jedis.hget(key, k));
                        }
                    }else{
                        value = jedis.hgetAll(key);
                    }
                    reMap.put("value", JSONObject.fromObject(value).toString());
                }catch (Exception e){
                    reMap = getValue(jedis, key, "list");
                }
                break;
            case "list" :
                //list类型的值
                try {
                    List<String> value = jedis.lrange(key, 0, -1);
                    reMap.put("value", JSONArray.fromObject(value).toString());
                }catch (Exception e){
                    reMap = getValue(jedis, key, "set");
                }
                break;
            case "set" :
                //set类型的值
                try {
                    Set<String> value = jedis.smembers(key);
                    reMap.put("value", JSONArray.fromObject(value).toString());
                }catch (Exception e){
                    reMap = getValue(jedis, key, "zset");
                }
                break;
            case "zset" :
                //有序set类型的值
                try {
                    Set<String> value = jedis.zrange(key, 0, -1);
                    reMap.put("value", JSONArray.fromObject(value).toString());
                }catch (Exception e){
                    reMap = null;
                }
                break;
            default:break;
        }
        return reMap;
    }

    private String addKey(Jedis jedis, String key, String valueType, String value){
        switch (valueType){
            case "string":
                jedis.set(key, value);
                break;
            default:
        }
        return "true";
    }

    /**
     * 根目录.
     * @return
     */
    @RequestMapping("/")
    public String index(){
        return "index/index";
    }

    /**
     * 获取redis的db信息.
     * @param request 请求
     * @return redis db信息
     */
    @RequestMapping(value = "/getRedisInfo")
    @ResponseBody
    public String getRedisInfo(HttpServletRequest request){
        String param = request.getParameter("param");
        String ip = request.getRemoteAddr();
        Jedis jedis = getJedis(ip, param.split(","));
        //获取db总数以及db里的key数
        List<String> dbs = new ArrayList();
        for(int i = 0;i < RedisClient.getMaxDbNumber(); i++){
            try {
                jedis.select(i);
                String db = i + "," + jedis.dbSize();
                dbs.add(db);
            }catch (Exception e){
                break;
            }
        }
        return JSONArray.fromObject(dbs).toString();
    }

    /**
     * 查询key.
     * @param request 请求信息
     * @return 所有db里匹配的key值
     */
    @RequestMapping(value = "/queryKey")
    @ResponseBody
    public String queryKey(HttpServletRequest request){
        String key = request.getParameter("key");
        String host = request.getParameter("host");
        String ip = request.getRemoteAddr();
        Jedis jedis = getJedis(ip, host.split(","));
        key = "*" + key +"*";
        //遍历所有db，并查询对应的key
        List<Map> dbs = new ArrayList();
        for(int i = 0;i < RedisClient.getMaxDbNumber(); i++){
            try {
                jedis.select(i);
                Set keys = jedis.keys(key);
                String db = i + "," + keys.size();
                Map map = new HashMap();
                map.put("db", db);
                map.put("keys", keys);
                dbs.add(map);
            }catch (Exception e){
                break;
            }
        }
        return JSONArray.fromObject(dbs).toString();
    }

    /**
     * 获取指定db的keys.
     * @param request 请求信息
     * @return 获取某个db的所有key
     */
    @RequestMapping(value = "/getDbKeys")
    @ResponseBody
    public String getDbKeys(HttpServletRequest request){
        String dbIndex = request.getParameter("dbIndex");
        String host = request.getParameter("host");
        String ip = request.getRemoteAddr();
        Jedis jedis = getJedis(ip, host.split(","));
        jedis.select(Integer.parseInt(dbIndex));
        String[] keys = jedis.keys("*").toArray(new String[0]);
        if(keys.length > RedisClient.getMaxKeyNumber()){
            List<String> tempKeys = new ArrayList<>();
            for(int i = 0;i < RedisClient.getMaxKeyNumber();i++){
                tempKeys.add(keys[i]);
            }
            keys = tempKeys.toArray(new String[0]);
        }
        return JSONArray.fromObject(keys).toString();
    }

    /**
     * 根据key取值.
     * @param request 请求信息
     * @return 某个db里某个key的值
     */
    @RequestMapping(value = "/getValue")
    @ResponseBody
    public String getValue(HttpServletRequest request){
        String dbIndex = request.getParameter("dbIndex");
        String key = request.getParameter("key");
        String host = request.getParameter("host");
        String ip = request.getRemoteAddr();
        Jedis jedis = getJedis(ip, host.split(","));
        jedis.select(Integer.parseInt(dbIndex));
        Map<String, String> reMap = getValue(jedis, key, "string");
        return JSONObject.fromObject(reMap).toString();
    }

    /**
     * 新增key.
     * @param request 请求信息
     * @return 新增结果
     */
    @RequestMapping(value = "/addKey")
    @ResponseBody
    public String addKey(HttpServletRequest request){
        String host = request.getParameter("host");
        String ip = request.getRemoteAddr();
        String dbIndex = request.getParameter("dbIndex");
        String key = request.getParameter("key");
        String valueType = request.getParameter("valueType");
        String value = request.getParameter("value");
        Jedis jedis = getJedis(ip, host.split(","));
        jedis.select(Integer.parseInt(dbIndex));
        return addKey(jedis, key, valueType, value);
    }

    /**
     * 是否存在key.
     * @param request 请求信息
     * @return 结果
     */
    @RequestMapping(value = "/exists")
    @ResponseBody
    public String exists(HttpServletRequest request){
        String host = request.getParameter("host");
        String ip = request.getRemoteAddr();
        String dbIndex = request.getParameter("dbIndex");
        String key = request.getParameter("key");
        Jedis jedis = getJedis(ip, host.split(","));
        jedis.select(Integer.parseInt(dbIndex));
        return jedis.exists(key).toString();
    }

}
